Before you can call SndPlayDoubleBuffer , you need to allocate two buffers (of type SndDoubleBuffer ), fill them both with data, set the flags for the two buffers to dbBufferReady , and then fill out a record of type SndDoubleBufferHeader with the appropriate information. Listing 1-44 illustrates how you can accomplish these tasks.
Listing 44 Setting up double buffers
CONST
kDoubleBufferSize = 4096; {size of each buffer (in bytes)}
TYPE
LocalVars = {variables used by the doubleback procedure}
RECORD
bytesTotal: LongInt; {total number of samples}
bytesCopied: LongInt; {number of samples copied to buffers}
dataPtr: Ptr; {pointer to sample to copy}
END;
LocalVarsPtr = ^LocalVars;
{This function uses SndPlayDoubleBuffer to play the sound specified.}
FUNCTION MyDBSndPlay (chan: SndChannelPtr; sndHeader: SoundHeaderPtr): OSErr;
VAR
myVars: LocalVars;
myDblHeader: SndDoubleBufferHeader;
myDblBuffer: SndDoubleBufferPtr;
myStatus: SCStatus;
myIndex: Integer;
myErr: OSErr;
BEGIN
{Set up myVars with initial information.}
myVars.bytesTotal := sndHeader^.length;
myVars.bytesCopied := 0; {no samples copied yet}
myVars.dataPtr := Ptr(@sndHeader^.sampleArea[0]);
{pointer to first sample}
{Set up SndDoubleBufferHeader.}
WITH myDblHeader DO
BEGIN
dbhNumChannels := 1; {one channel}
dbhSampleSize := 8; {8-bit samples}
dbhCompressionID := 0; {no compression}
dbhPacketSize := 0; {no compression}
dbhSampleRate := sndHeader^.sampleRate;
dbhDoubleBack := @MyDoubleBackProc;
END;
FOR myIndex := 0 TO 1 DO {initialize both buffers}
BEGIN
{Get memory for double buffer.}
myDblBuffer := SndDoubleBufferPtr(NewPtr(Sizeof(SndDoubleBuffer) +
kDoubleBufferSize));
IF myDblBuffer = NIL THEN
BEGIN
MyDBSndPlay := MemError;
Exit(MyDBSndPlay);
END;
myDblBuffer^.dbNumFrames := 0; {no frames yet}
myDblBuffer^.dbFlags := 0; {buffer is empty}
myDblBuffer^.dbUserInfo[0] := LongInt(@myVars);
{Fill buffer with samples.}
MyDoubleBackProc(sndChan, myDblBuffer);
{Store buffer pointer in header.}
myDblHeader.dbhBufferPtr[myIndex] := myDblBuffer;
END;
{Start the sound playing.}
myErr := SndPlayDoubleBuffer(sndChan, @myDblHeader);
IF myErr <> noErr THEN
BEGIN
MyDBSndPlay := myErr;
Exit(MyDBSndPlay);
END;
{Wait for the sound's end by checking the channel status.}
REPEAT
myErr := SndChannelStatus(chan, sizeof(myStatus), @status);
UNTIL NOT myStatus.scChannelBusy;
{Dispose double buffer memory.}
FOR myIndex := 0 TO 1 DO
DisposePtr(Ptr(myDblHeader.dbhBufferPtr[myIndex]));
MyDBSndPlay := noErr;
END;
The function MyDBSndPlay takes two parameters, a pointer to a sound channel and a pointer to a sound header. For information about obtaining a pointer to a sound header, see "Obtaining a Pointer to a Sound Header" . The MyDBSndPlay function reads the sound header to determine the characteristics of the sound to be played (for example, how many samples are to be sent into the sound channel). Then MyDBSndPlay fills in the fields of the double buffer header, creates two buffers, and starts the sound playing. The doubleback procedure MyDoubleBackProc is defined in the next section.
| Previous | Chapter contents | Chapter top | Section top | Next |